inspector: fix a crash in the CSS editor
authorSébastien Wilmet <swilmet@gnome.org>
Sun, 24 Aug 2014 18:27:13 +0000 (20:27 +0200)
committerSébastien Wilmet <swilmet@gnome.org>
Mon, 25 Aug 2014 12:25:09 +0000 (14:25 +0200)
gtk_css_section_get_end_position() can return a position one byte beyond
the end of the last line.

gtk_text_buffer_get_iter_at_line_index() accepts only valid
line_number/byte_index pairs. Another solution is to make the
GtkTextBuffer function less strict, by returning a boolean if the exact
position was found.

The CSS parser should also be fixed to always return valid positions.
But it's better to have a safety net in the CSS editor, just in case (a
warning could be print).

https://bugzilla.gnome.org/show_bug.cgi?id=735337

gtk/inspector/css-editor.c

index 33c78770711b98884cc5952bfe890b8f6e75e4d1..d8f518192036bc8df041e6d40f0596ec70b8b495 100644 (file)
@@ -259,6 +259,27 @@ text_changed (GtkTextBuffer         *buffer,
   ce->priv->timeout = g_timeout_add (100, update_timeout, ce); 
 }
 
+/* Safe version of gtk_text_buffer_get_iter_at_line_index(). */
+static void
+safe_get_iter_at_line_index (GtkTextBuffer *buffer,
+                             GtkTextIter   *iter,
+                             gint           line_number,
+                             gint           byte_index)
+{
+  if (line_number >= gtk_text_buffer_get_line_count (buffer))
+    {
+      gtk_text_buffer_get_end_iter (buffer, iter);
+      return;
+    }
+
+  gtk_text_buffer_get_iter_at_line (buffer, iter, line_number);
+
+  if (byte_index < gtk_text_iter_get_bytes_in_line (iter))
+    gtk_text_iter_set_line_index (iter, byte_index);
+  else
+    gtk_text_iter_forward_to_line_end (iter);
+}
+
 static void
 show_parsing_error (GtkCssProvider        *provider,
                     GtkCssSection         *section,
@@ -269,14 +290,14 @@ show_parsing_error (GtkCssProvider        *provider,
   const char *tag_name;
   GtkTextBuffer *buffer = GTK_TEXT_BUFFER (ce->priv->text);
 
-  gtk_text_buffer_get_iter_at_line_index (buffer,
-                                          &start,
-                                          gtk_css_section_get_start_line (section),
-                                          gtk_css_section_get_start_position (section));
-  gtk_text_buffer_get_iter_at_line_index (buffer,
-                                          &end,
-                                          gtk_css_section_get_end_line (section),
-                                          gtk_css_section_get_end_position (section));
+  safe_get_iter_at_line_index (buffer,
+                               &start,
+                               gtk_css_section_get_start_line (section),
+                               gtk_css_section_get_start_position (section));
+  safe_get_iter_at_line_index (buffer,
+                               &end,
+                               gtk_css_section_get_end_line (section),
+                               gtk_css_section_get_end_position (section));
 
   if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
     tag_name = "warning";